/*
 * @Author: Wangtao
 * @Date: 2020-11-10 14:13:21
 * @LastEditors: Wangtao
 * @LastEditTime: 2020-11-27 18:02:19
 */
import store from '../store'
import { commonAction } from './common'
import { CommonModule } from '../store/modules/common'
export default {
  install (Vue, options) {
    // 获取指定的缓存， url: 请求地址， types: []要取的缓存类型，hasObj 是否需要转换成_id为key的数据, formServer: 是否重新请求, hideLoading: 是否展示遮罩，默认有遮罩 isTree是否处理树形结构,  method: 请求方式, reslevel: 数据响应层级, data: 请求参数
    Vue.prototype.$getCache = (url: string, types: any, hasObj: boolean, formServer: boolean, hideLoading: boolean, method: string, isTree: boolean, reslevel: string, data?: any) => {
      let newTypes: any[] = [] // vuex中存在，不需要再次请求
      const resData = {}
      const publicCache = store.state.common.publicCache
      if (formServer) { // 全部从服务端获取最新的数据
        newTypes = types
      } else { // 过滤，vuex不存在的，才请求服务端数据
        types.forEach((item: string) => {
          const existArr = publicCache[item] && Array.isArray(publicCache[item]) && publicCache[item].length > 0 // 缓存的为数组
          const exsitObj = publicCache[item] && publicCache[item].constructor === Object && Object.keys(publicCache[item]).length > 0 // 缓存的为对象
          if (existArr || exsitObj) { // vuex中有
            resData[item] = publicCache[item]
          } else { // vuex中不存在，请求服务端数据
            newTypes.push(item)
          }
        })
      }
      if (newTypes.length > 0) { // 有需要重新发请求的类型
        let actionData = {}
        if (reslevel) {
          actionData = {
            url, method, data
          }
        } else {
          actionData = {
            url, method: 'POST', data: { types: newTypes }, hideLoading
          }
        }
        return commonAction(actionData).then((resp: any) => {
          if (resp && resp.success) {
            const isNeedTree = isTree || false
            newTypes.forEach((item: string) => {
              if (reslevel) {
                CommonModule.newSetPubCache({ resp, type: item, reslevel, hasObj })
              } else {
                CommonModule.setPublicCache({ data: resp[item] ? resp[item] : [], type: item, hasObj, isNeedTree })
              }
            })
            return { ...resp, ...resData } // 新请求回来的 + vuex中取回的
          } else {
            return resData // 直接返回vuex中的数据
          }
        }).catch((err: any) => {
          console.log(err)
          return resData // 直接返回vuex中的数据
        })
      } else {
        return new Promise((resolve) => { // 直接返回vuex中的数据
          resolve(resData)
        })
      }
    }
    // 更新指定的缓存(更新整个data对象替换)， type:单个缓存的类型, data:要更新的对象， key: 用来匹配的key, 比如: _id, hasObj 是否需要转换成_id为key的数据
    Vue.prototype.$updateCache = (type: string, data: any, key: string, hasObj: boolean) => {
      const publicCache = store.state.common.publicCache
      const currentArr = publicCache[type] || []
      const newArr: any[] = []
      if (currentArr && currentArr.length > 0) { // 找到指定的数据对象
        currentArr.forEach((item: any) => {
          item[key] === data[key] ? newArr.push(data) : newArr.push(item) // 标识key相等，更新数据
        })
        CommonModule.setPublicCache({ data: newArr, type, hasObj }) // hasObj会把对应的keyobj的数据也同时更新
      }
    }
    // 更新指定的缓存（只替换某个字段eg: 停用/启用）， type:单个缓存的类型, resplaceData: { _id: 'xxxx',key: 'status', value: 'enable'}, replaceKey: 用来匹配的key, 比如: _id,  hasObj 是否需要转换成_id为key的数据
    Vue.prototype.$updateCacheBySingleKey = (type: string, resplaceData: any, replaceKey: string, hasObj: boolean) => {
      const publicCache = store.state.common.publicCache
      const currentArr = publicCache[type] || []
      const newArr: any[] = []
      if (currentArr && currentArr.length > 0) { // 找到指定的数据对象
        currentArr.forEach((item: any) => {
          if (item[replaceKey] === resplaceData[replaceKey] && (item[resplaceData.key] || (item[resplaceData.key] === false))) {
            item[resplaceData.key] = resplaceData.value
          }
          newArr.push(item)
        })
        CommonModule.setPublicCache({ data: newArr, type, hasObj }) // hasObj会把对应的keyobj的数据也同时更新
      }
    }
    // 往缓存中新加数据，type:单个缓存的类型,data: 要添加的对象， hasObj 是否需要转换成_id为key的数据
    Vue.prototype.$addOneCache = (type: string, data: any, hasObj: boolean) => {
      const publicCache = store.state.common.publicCache
      const currentArr = publicCache[type] || []
      if (currentArr.length <= 0) { // 没有相关缓存，让用的地方自己发请求拉最新数据（否则会导致当前新加了数据，使用的模块不发请求）
        return false
      }
      currentArr.push(data)
      CommonModule.setPublicCache({ data: currentArr, type, hasObj }) // hasObj会把对应的keyobj的数据也同时更新
    }
    // 删除某条数据，type:单个缓存的类型,key: 用来匹配的key, 比如: _id, value: key对应的值，hasObj 是否需要转换成_id为key的数据
    Vue.prototype.$deleteCache = (type: string, key: string, value: string, hasObj: boolean) => {
      const publicCache = store.state.common.publicCache
      const currentArr = publicCache[type] || []
      const newArr: any[] = []
      if (currentArr && currentArr.length > 0) { // 找到指定的数据对象
        currentArr.forEach((item: any) => {
          if (item[key] !== value) { // 标识key相等，更新数据
            newArr.push(item)
          }
        })
        CommonModule.setPublicCache({ data: newArr, type, hasObj }) // hasObj会把对应的keyobj的数据也同时更新
      }
    }
  }
}
